package zzs.generalframework.util.core.reflect;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.stereotype.Component;

import net.sf.cglib.beans.BeanCopier;
import net.sf.cglib.beans.BeanMap;
import net.sf.cglib.core.Converter;
import zzs.generalframework.util.core.calendar.CalendarUtils;

/**
 * @title
 * @description
 * @project zzs-util
 * @package zzs.generalframework.util.core.reflect
 * @author zzs
 * @date 2018年1月30日
 * @version 1.0
 */
@Component("zzs.generalframework.util.core.reflect.beanUtils")
public class BeanUtils
{

	public void copyBean(Object fromObj, Object toObj) throws InstantiationException, IllegalAccessException
	{
		copyBean(fromObj, toObj, false);
	}

	public void copyBean(Object fromObj, Object toObj, boolean isConverter) throws InstantiationException, IllegalAccessException
	{
		BeanCopier beanCopier = BeanCopier.create(fromObj.getClass(), toObj.getClass(), isConverter);
		if (isConverter)
		{
			Converter converter = new FieldTypeConverter();
			beanCopier.copy(fromObj, toObj, converter);
		}
		else
		{
			beanCopier.copy(fromObj, toObj, null);
		}
		beanCopier = null;
	}

	public void copyBeanNotNull(Object fromObj, Object toObj)
	{
		Map<String, Object> notNullMap = new HashMap<String, Object>();
		copyBean2MapNotNull(fromObj, notNullMap);
		copyMap2Bean(notNullMap, toObj);
		notNullMap = null;
	}

	public void copyBean2Map(Object fromObj, Map<String, Object> toMap)
	{
		BeanMap beanMap = BeanMap.create(fromObj);
		Set keySet = beanMap.keySet();
		for (Object itemKey : keySet)
		{
			toMap.put(itemKey.toString(), beanMap.get(itemKey));
		}
	}

	public void copyBean2MapNotNull(Object fromObj, Map<String, Object> toMap)
	{
		BeanMap beanMap = BeanMap.create(fromObj);
		Set keySet = beanMap.keySet();
		for (Object itemKey : keySet)
		{
			Object value = beanMap.get(itemKey);
			if (value != null)
			{
				toMap.put(itemKey.toString(), value);
			}
		}
	}

	public void copyBean2MapNull2ZeroString(Object fromObj, Map<String, Object> toMap)
	{
		BeanMap beanMap = BeanMap.create(fromObj);
		Set keySet = beanMap.keySet();
		for (Object itemKey : keySet)
		{
			Object value = beanMap.get(itemKey);
			if (value == null)
			{
				value = "";
			}
			toMap.put(itemKey.toString(), value);
		}
	}

	public void copyMap2Bean(Map<String, Object> fromMap, Object toObj, boolean isConverter)
	{
		if (!isConverter)
		{
			BeanMap beanMap = BeanMap.create(toObj);
			beanMap.putAll(fromMap);
		}
		else
		{
			BeanMap beanMap = BeanMap.create(toObj);
			Map<String, Object> srcMap = new HashMap<String, Object>();
			Map<String, String> beanFieldTypeMap = ClassUtils.getFieldTypeMap(toObj.getClass());
			for (Entry<String, Object> itemEntry : fromMap.entrySet())
			{
				String key = itemEntry.getKey();
				Object value = itemEntry.getValue();
				value = convererValue(value, beanFieldTypeMap.get(key));
				srcMap.put(key, value);
			}
			beanMap.putAll(srcMap);
		}
	}

	public void copyMap2Bean(Map<String, Object> fromMap, Object toObj)
	{
		copyMap2Bean(fromMap, toObj, false);
	}

	public void copyMap2BeanNotNull(Map<String, Object> fromMap, Object toObj)
	{
		BeanMap beanMap = BeanMap.create(toObj);
		Map<String, Object> srcMap = new HashMap<String, Object>();
		for (Entry<String, Object> itemEntry : fromMap.entrySet())
		{
			String key = itemEntry.getKey();
			Object value = itemEntry.getValue();
			if (value != null)
			{
				srcMap.put(key, value);
			}
		}
		beanMap.putAll(srcMap);
	}

	public void copyMap2BeanNull2ZeroString(Map<String, Object> fromMap, Object toObj)
	{
		BeanMap beanMap = BeanMap.create(toObj);
		Map<String, Object> srcMap = new HashMap<String, Object>();
		for (Entry<String, Object> itemEntry : fromMap.entrySet())
		{
			String key = itemEntry.getKey();
			Object value = itemEntry.getValue();
			if (value == null)
			{
				value = "";
			}
			srcMap.put(key, value);
		}
		beanMap.putAll(srcMap);
	}

	private Object convererValue(Object srcValue, String fieldType)
	{
		Object returnObj = null;
		if (srcValue != null && fieldType != null)
		{
			if (fieldType.contains("Date"))
			{
				try
				{
					returnObj = CalendarUtils.convertString2Date(srcValue.toString());
				}
				catch (ParseException e)
				{
					e.printStackTrace();
				}
			}
			else if (fieldType.contains("BigDecimal"))
			{
				returnObj = new BigDecimal(srcValue.toString());
			}
			else if (fieldType.contains("Integer"))
			{
				returnObj = new Integer(srcValue.toString());
			}
			else
			{
				returnObj = srcValue.toString();
			}
		}
		return returnObj;
	}

}
